#include "visage.h"


C_dessine_visage::C_dessine_visage(IplImage *ipl)
{
    image = cvCloneImage(ipl);
    //image = cvLoadImage("images/Profil.jpg");
    //cout<<"TAILE :: "<<ipl->height<<endl;

    // Number of tracked pixels
    int nbPixels=0;

    // Next position of the object we overlay
    CvPoint objectNextPos = cvPoint(-1, -1);

    cvNamedWindow("GeckoGeek Color Tracking", 400);

    cvNamedWindow("GeckoGeek Mask", 400);
    cvMoveWindow("GeckoGeek Color Tracking", 0, 100);
    cvMoveWindow("GeckoGeek Mask", 650, 100);

    //("GeckoGeek Color Tracking",image);

    // cvWaitKey(100);

    // We get the current image
    //cvShowImage("GeckoGeek Color Tracking",image);

    // If there is no image, we exit the loop

    objectNextPos = binarisation(image, &nbPixels);
    //("GeckoGeek Mask",binair);

    // Destroy the windows we have created
    cvDestroyWindow("GeckoGeek Color Tracking");
    cvDestroyWindow("GeckoGeek Mask");
}

CvPoint C_dessine_visage::trouvelegato(IplImage* p_image_b)
{
    CvScalar scal;

    int l_x=000;
    int l_y=001;

    do
    {
        l_x=01;
        l_y++;

            do{
                l_x++;
                scal=cvGet2D(p_image_b, l_y, l_x);
                if (scal.val[0]!=0)
                {
                    break;
                }
            } while(l_x< ((p_image_b->width)-02));

            if (scal.val[0]!=0)
            {
                break;
            }

    } while(l_y<p_image_b->height);


   // cvWaitKey();
    return cvPoint(l_y,l_x);

}

S_point C_dessine_visage::pointSuivant(IplImage* img_contour,CvPoint precd,int direction)
{
    CvScalar scal;

    S_point le_point;
    le_point.dir=direction;
    le_point.x=0;
    le_point.y=0;
    int index=0;

    do
    {
        direction++;
        direction= direction%4;

        switch (direction)
        {
            case 0 :
                    scal= cvGet2D(img_contour,precd.x+1,precd.y);

                    le_point.dir=0;
                    le_point.x=precd.x+1;
                    le_point.y=precd.y;
                    //cvSet2D(img_contour,precd.x+1,precd.y,)
                    break;

            case 1 :
                    scal= cvGet2D(img_contour,precd.x,precd.y-1);

                    le_point.dir=1;
                    le_point.x=precd.x;
                    le_point.y=precd.y-1;
                    break;

            case 2 :
                    scal= cvGet2D(img_contour,precd.x-1,precd.y);

                    le_point.dir=2;
                    le_point.x=precd.x-1;
                    le_point.y=precd.y;
                    break;

            case 3 :
                    scal= cvGet2D(img_contour,precd.x,precd.y+1);

                    le_point.dir=3;
                    le_point.x=precd.x;
                    le_point.y=precd.y+1;
                    break;
                    default :printf("erueur");

        }
        printf("direction %d",direction);

        index++;
        if(index>4){ le_point.dir=-1;return le_point;}

    } while((scal.val[0]<100));

    scal.val[0]=126;
    cvSet2D(img_contour,le_point.x,le_point.y,scal);

    cvSet2D(img_contour,1,1,scal);
    cvSet2D(img_contour,1,2,scal);
    cvSet2D(img_contour,1,3,scal);
    cvSet2D(img_contour,1,4,scal);
    cvSet2D(img_contour,1,5,scal);
    cvSet2D(img_contour,1,6,scal);
    cvSet2D(img_contour,1,7,scal);
    scal.val[0]=226;
    cvSet2D(img_contour,1,1,scal);
    cvSet2D(img_contour,2,1,scal);
    cvSet2D(img_contour,3,1,scal);
    cvSet2D(img_contour,4,1,scal);
    cvSet2D(img_contour,5,1,scal);
    cvSet2D(img_contour,6,1,scal);
    cvSet2D(img_contour,7,1,scal);


    //cvShowImage("GeckoGeek Color binaire",img_contour);
     //   cvWaitKey(10);

    return le_point;
}

void C_dessine_visage::findPoint()
{
    CvPoint poinPremier;
    S_point pointContour[1800];
    //--- tangente de 2 point ---
   // ("binaire", this->binair);

    poinPremier=trouvelegato(this->binair);
    pointContour[0].x= poinPremier.x;
    pointContour[0].y= poinPremier.y;
    pointContour[0].dir=0;
    pointContour[1].x= 0;
    pointContour[1].y= 0;
    pointContour[1].dir=0;
    int i=1;
    int x1,y1;
    int xtmp1,ytmp1;

    do //1597poin pour faire le tour
    {
        pointContour[i]=pointSuivant(binair,cvPoint(pointContour[i-1].x,pointContour[i-1].y),(pointContour[i-1].dir+2)%4);
        printf("\n premier poin du contour x: %d y: %d\n",pointContour[i].x, pointContour[i].y);

        if(pointContour[i].dir==-1) break;

        if(i==1798)
        {
                break;
        }

        if(i==5)
        {
            x1= pointContour[1].x;
            y1= pointContour[1].y;
        }

        xtmp1=pointContour[i].x;
        ytmp1=pointContour[i].y;
        printf("\n i :%d",i);

        i++;
    } while((x1!=xtmp1)||(y1!=ytmp1));

    int direrctionOrigine= pointContour[0].dir;
    int direction2=0;

    for(int index=1;index<i;index++)
    {
        direction2=pointContour[index].dir;

        if(direction2!=direrctionOrigine)
        {
                direrctionOrigine=pointContour[index].dir;
                pointFinal.push_back(pointContour[index]);
        }
    }

    IplImage *image_de_points =cvLoadImage("profile1.jpg");

    CvScalar scal;

    scal.val[0]=00;
    scal.val[0]=226;

    int index1=0;
    int condition=pointFinal.size()-2;
    /*
    while(index1<condition)
    {
        cvSet2D(image_de_points,pointFinal[index1].x,pointFinal[index1].y,scal);
        index1++;
    }*/

    //(" contour",image_de_points);
    //cvWaitKey(100000);

    //////////////////////////////////////////////////////////////////////////
    //////////////////////// simplification2 /////////////////////////////////
    //////////////////////////////////////////////////////////////////////////
    int xtmpA, ytmpA,Acarrex,Acarrey;
    int xtmpB, ytmpB,Bcarrex,Bcarrey;
    int compteur=0;
    int compteur1=0;
    float AaB,BaAD;
    float AD;

    image_de_points =cvLoadImage("profile1.jpg");

    do
    {
        //__________AD _________
        xtmpA= ( pointContour[compteur+2].x-pointContour[compteur1].x);
        ytmpA= ( pointContour[compteur+2].y-pointContour[compteur1].y);
        Acarrex=xtmpA*xtmpA;
        Acarrey=ytmpA*ytmpA;
        AD=(float)Acarrex+Acarrey;
        AD= sqrtf(AD);
        //__________AaB _________
        xtmpB= ( pointContour[compteur+1].x-pointContour[compteur1].x);
        ytmpB= ( pointContour[compteur+1].y-pointContour[compteur1].y);
        Bcarrex=xtmpB*xtmpB;
        Bcarrey=ytmpB*ytmpB;
        AaB=(float)Bcarrex+Acarrey;
        AaB= sqrtf(AaB);
        //__________BaAD _________
        AaB=AaB*AaB;
        AD=AD/2;
        AD=AD*AD;
        AaB=AaB*AaB;
        BaAD=AaB-AD;
        BaAD= sqrtf(BaAD);
        if(BaAD>3)
        {
                pointFinal2.push_back(pointContour[compteur+1]);
                compteur1=compteur+1;
        }
        compteur++;
    } while(compteur<i-2);

    cout<<"point final2 : "<<pointFinal2.size()<<endl;
    index1=0;
    condition=pointFinal2.size()-2;

   /* while(index1<condition)
    {
        cvSet2D(image_de_points,pointFinal2[index1].x,pointFinal2[index1].y,scal);
        index1++;
    }*/

    //(" contour2",image_de_points);
    //cvWaitKey(100000);

    cout<<"fin";

    //////////////////////////////////////////////////////////////////////////
    //////////////////////// simplification2 /////////////////////////////////
    //////////////////////////////////////////////////////////////////////////

    compteur=0;
    compteur1=0;

    //image_de_points =cvLoadImage("profile1.jpg");
    condition= pointFinal.size()-2;

    do
    {
        //__________AD _________
        xtmpA= ( pointFinal[compteur+2].x-pointFinal[compteur1].x);
        ytmpA= ( pointFinal[compteur+2].y-pointFinal[compteur1].y);
        Acarrex=xtmpA*xtmpA;
        Acarrey=ytmpA*ytmpA;
        AD=(float)Acarrex+Acarrey;
        AD= sqrtf(AD);
        //__________AaB _________
        xtmpB= ( pointFinal[compteur+1].x-pointFinal[compteur1].x);
        ytmpB= ( pointFinal[compteur+1].y-pointFinal[compteur1].y);
        Bcarrex=xtmpB*xtmpB;
        Bcarrey=ytmpB*ytmpB;
        AaB=(float)Bcarrex+Acarrey;
        AaB= sqrtf(AaB);
        //__________BaAD _________
        AaB=AaB*AaB;
        AD=AD/2;
        AD=AD*AD;
        AaB=AaB*AaB;
        BaAD=AaB-AD;
        BaAD= sqrtf(BaAD);

        if(BaAD>3)
        {
                pointFinal3.push_back(pointFinal[compteur+1]);
                compteur1=compteur+1;
        }
        compteur++;
    } while(compteur<condition);
    cout<<"point final3: "<<pointFinal3.size()<<endl;

    index1=0;
    condition=pointFinal3.size()-2;

    /*while(index1<condition)
    {
        cvSet2D(image_de_points,pointFinal3[index1].x,pointFinal3[index1].y,scal);
        index1++;
    }*/

  //  (" contour3",image_de_points);
   // cvWaitKey(100000);
    cout<<"contour calculer";

}

CvPoint C_dessine_visage::binarisation(IplImage* image, int *nbPixels) 
{
    CvScalar pixel;
    IplImage  *mask;
    IplConvKernel *kernel;

    int sommeX = 0, sommeY = 0;
    *nbPixels = 0;


    // Create the mask &initialize it to white (no color detected)
    mask = cvCreateImage(cvGetSize(image), image->depth, 1);

    // We create the mask
    cvInRangeS(image, cvScalar(h - tolerance -1, s - tolerance, 0), cvScalar(h + tolerance -1, s + tolerance, 255), mask);

    //CvScalar pixel ;

    // Create kernels for the morphological operation
    kernel = cvCreateStructuringElementEx(15, 15, 2, 2, CV_SHAPE_ELLIPSE);
    //modifie les bords pour exploité  les contour

    IplImage* g_gray = cvCreateImage( cvGetSize( image ), 8, 1 );

    cvCvtColor( image, g_gray, CV_BGR2GRAY );
    cvThreshold( g_gray,mask , 127, 255, CV_THRESH_BINARY_INV );

    for(int index=0;index<mask->height;index++)
    {
        pixel.val[0]=0;
        pixel.val[1]=0;
        pixel.val[2]=0;
        cvSet2D(mask,mask->height-1,index,pixel);
    }

    cvErode(mask, mask, kernel, 1);

    this->binair=cvCloneImage(mask);

    //cvCanny(binair,binair,10,100,3);

    findPoint();

    // We release the memory of kernels
    cvReleaseStructuringElement(&kernel);

    // We release the memory of the mask
    cvReleaseImage(&mask);

    // We release the memory of the hsv image
    cvReleaseImage(&binair);

    // If there is no pixel, we return a center outside the image, else we return the center of gravity
    if(*nbPixels > 0)
        return cvPoint((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels)));
    else
        return cvPoint(-1, -1);
}

vector<S_point> C_dessine_visage::getvector(int i)
{
    switch(i){
    case 1:
        return this->pointFinal;
        break;

    case 2:
        return this->pointFinal2;
        break;

    case 3:
        return this->pointFinal3;
        break;
    };

    return pointFinal;
}
